package block

import (
	pow2 "Blockchain/pow"
	"Blockchain/tools"
	"bytes"
	"encoding/gob"
	"strconv"
	"time"
)

type Block struct {
	PrevHash []byte
	TimeStamp int64
	Data []byte
	Nonce int64
	Hash []byte

}
func CreateBlock(data []byte,prevHash []byte)*Block {
	block := Block{
		PrevHash:  prevHash,
		TimeStamp: time.Now().Unix(),
		Data:      data,
	}
	pow := pow2.NewPow(block.Data, block.TimeStamp, block.PrevHash)
	hash, nonce := pow.Run()
	block.Hash = hash
	block.Nonce = nonce
	return &block
}
/**
   * 序列化：把结构体进行有序的排列
  	把block转成[]byte
*/
func(block *Block)Serialize()([]byte,error){
	var result bytes.Buffer
	en := gob.NewEncoder(&result)

	err:= en.Encode(block)
	if err !=nil{
		return nil,err
	}
	return result.Bytes(), nil
}

/**
 * 反序列化：把[]byte转会block
 */
func DeSerialize(data []byte)(*Block,error){
	reader := bytes.NewReader(data)
	de := gob.NewDecoder(reader)
	var block *Block
	err := de.Decode(&block)
	if err !=nil{
		return nil, err
	}
	return block,nil
}



func (block *Block)GetHash()[]byte{

	timeByte:=[]byte(strconv.FormatInt(block.TimeStamp,10))
	nonceByte:=[]byte(strconv.FormatInt(block.Nonce,10))
	hashByte:=bytes.Join([][]byte{block.PrevHash,block.Data,timeByte,nonceByte},[]byte{})

	return tools.SetHash(hashByte)
}

func CreateGenesis(data []byte)*Block{
	return CreateBlock(data,nil)
}
